#include <gtk-3.0/gdk/gdk.h>


GdkWindow* create_window(void)
{
    GdkWindow* res = NULL;
    GdkWindow* root;
    root = gdk_screen_get_root_window(gdk_screen_get_default());

    GdkWindowAttr attr;
    gint attr_mask;
    attr_mask = GDK_WA_TITLE | GDK_WA_X | GDK_WA_Y | GDK_WA_TYPE_HINT;
    // attr_mask |= GDK_WA_VISUAL;
    attr.title = "a02_hello";
    attr.event_mask = GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
    attr.event_mask |= GDK_STRUCTURE_MASK;        //ConfigureNotify
    // attr.event_mask = GDK_ALL_EVENTS_MASK;
    attr.width = 400;
    attr.height = 300;
    // attr.window_type = GDK_WINDOW_CHILD;
    attr.window_type = GDK_WINDOW_TOPLEVEL;         //child window没有GDK_CONFIGURE event
    attr.wclass = GDK_INPUT_OUTPUT;    

    attr.x = attr.y = 100;
    attr.type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
    // attr.visual = gdk_screen_get_system_visual(gdk_screen_get_default());

    res = gdk_window_new(root, &attr, attr_mask);    

    return res;
}

void draw_background(cairo_t *cr, GdkRectangle *rect)
{
    g_print("draw_background():  %d,%d,%d,%d\n", rect->x, rect->y, rect->width, rect->height);        
    cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height);
    // cairo_set_line_width (cr, 5);
    cairo_set_source_rgba(cr, 0.7,0.7,0.7, 1);
    cairo_fill(cr);
}

void draw_text(cairo_t *cr, GdkRectangle *rect)
{
    g_print("draw_text():\n");        

    PangoLayout *layout;
    PangoFontDescription *desc;

    cairo_set_source_rgb(cr, 1, 0, 0);
    layout = pango_cairo_create_layout (cr);

// #define FONT "Sans Bold 27"
#define FONT "Sans 27"
    desc = pango_font_description_from_string (FONT);
    pango_layout_set_font_description (layout, desc);
    pango_font_description_free (desc);

    pango_layout_set_text (layout, "Hello, the world!", -1);

    guint width, height;
    // pango_cairo_update_layout (cr, layout);
    pango_layout_get_size (layout, &width, &height);
    width = width / PANGO_SCALE;
    height = height / PANGO_SCALE;    
    cairo_move_to (cr, (rect->width - width) / 2, (rect->height - height) / 2);
    pango_cairo_show_layout (cr, layout);   //画在current point位置

    g_object_unref (layout);

        
}

void event_proc(GdkEvent *event, gpointer data)
{
    // GdkDisplay *display = data;

    g_print("---------------------------------------------------\n");
    g_print("type=%d\n", gdk_event_get_event_type(event));
    switch(gdk_event_get_event_type(event))
    {
        case GDK_DELETE:
        {
            GMainLoop *loop = data;
            gdk_window_destroy(event->any.window);
            g_main_loop_quit (loop);
        }
            break;
        
        case GDK_EXPOSE:
        {
            g_print("GDK_EXPOSE event\n");
            GdkRectangle *rect = &event->expose.area;
            GdkDrawingContext *ctx;
            ctx = gdk_window_begin_draw_frame(event->expose.window, event->expose.region);
            
            cairo_t *cr;
            cr = gdk_drawing_context_get_cairo_context(ctx);
            draw_background(cr, rect);
            draw_text(cr, rect);
            gdk_window_end_draw_frame(event->expose.window, ctx);
        }
            break;
        case GDK_CONFIGURE:
        {
            g_print("GDK_CONFIGURE event\n");

            GdkRectangle rect;
            // rect.x = event->configure.x;
            // rect.y = event->configure.y;
            rect.x = 0;
            rect.y = 0;
            rect.width = event->configure.width;
            rect.height = event->configure.height;

            cairo_region_t *region;
            region = cairo_region_create_rectangle(&rect);

            GdkDrawingContext *ctx;
            ctx = gdk_window_begin_draw_frame(event->expose.window, region);
            cairo_region_destroy (region);

            cairo_t *cr;
            cr = gdk_drawing_context_get_cairo_context(ctx);
            draw_background(cr, &rect);
            draw_text(cr, &rect);
            gdk_window_end_draw_frame(event->expose.window, ctx);

        }
            break;
        case GDK_VISIBILITY_NOTIFY:
        {
            g_print("GDK_VISIBILITY_NOTIFY event\n");
        }
            break;
        case GDK_BUTTON_PRESS:
        {
            g_print("GDK_BUTTON_PRESS event\n");
            // loop = FALSE;
        }
            break;                
        default:
            break;
    }

}

int main(int argc, char* argv[])
{
    g_print("a02_hello.......begin..\n");


    GMainLoop *loop;
    loop = g_main_loop_new(NULL, TRUE);

    gdk_init(&argc, &argv);
    gdk_set_show_events(TRUE);

    GdkDisplay *display;
    display = gdk_display_get_default();

    gdk_event_handler_set(event_proc, (gpointer)loop, NULL);

    GdkWindow *window;

    window = create_window();
    g_assert(window);

    // GdkRGBA bg={0,1,0,1};
    // gdk_window_set_background_rgba(window, &bg);

    gdk_window_show(window);
    // gdk_window_invalidate_rect(window, NULL, TRUE);

#if 1
    g_main_loop_run (loop);
    g_main_loop_unref (loop);


#else
    GdkEvent *event;
    gboolean loop = TRUE;

    while(loop)
    {
        // event = gdk_display_get_event(display);
        event = gdk_event_get();
        if(!event)
        {
            // g_print(".");
            continue;
        }
    
        // g_assert(event);

        g_print("----\n");
        g_print("type=%d\n", gdk_event_get_event_type(event));
        switch(gdk_event_get_event_type(event))
        {
            case GDK_EXPOSE:
            {
                g_print("GDK_EXPOSE event\n");
                GdkRectangle *rect = &event->expose.area;
                g_print("\t %d,%d,%d,%d\n", rect->x, rect->y, rect->width, rect->height);

                GdkDrawingContext *ctx;
                ctx = gdk_window_begin_draw_frame(event->expose.window, event->expose.region);

                cairo_t *cr;                

                cr = gdk_drawing_context_get_cairo_context(ctx);
                cairo_rectangle(cr, rect->x, rect->y, rect->width, rect->height);
                cairo_set_line_width (cr, 5);
                cairo_set_source_rgba(cr, 1,0,0, 1);
                cairo_fill(cr);

                gdk_window_end_draw_frame(event->expose.window, ctx);
            }
                break;
            case GDK_VISIBILITY_NOTIFY:
            {
                g_print("GDK_VISIBILITY_NOTIFY event\n");
            }
                break;
            case GDK_BUTTON_PRESS:
            {
                g_print("GDK_BUTTON_PRESS event\n");
                // loop = FALSE;
            }
                break;                
            default:
                break;
        }

        gdk_event_free(event);
    }
#endif

    // gdk_window_destroy(window);
    g_assert(gdk_window_is_destroyed (window));

    g_print("a02_hello.......over...\n");
    return 0;
}